package com.tongji;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class CommondThread extends Thread {
	public static final short COMMOND_SIZE = 0x01;
	public static final short COMMOND_POS = 0x02;
	public static final short COMMOND_DOWN = 0x03;
	public static final short COMMOND_UP = 0x04;
	public static final short COMMOND_CLICK	= 0x05;
	public static final short COMMOND_MOVE = 0x06;
	public static final short COMMOND_PRESS = 0x07;
	
	public Handler mHandler;
	
	private String mAddress;
	private boolean mConnected = false;
	private Socket mCommondSocket;
	private OutputStream mCommondStream;
	private InputStream mConfirmStream;
	private byte sendBuffer[] = new byte[12];
	
	public CommondThread(String address) {
		mAddress = address;
	}
	
	public void run() {
		Looper.prepare();
		mHandler = new Handler() {
            public void handleMessage(Message msg) {
                Bundle data = msg.getData();
                if (mConnected == false) {
                	mConnected = true;
                	connect();
                }
                @SuppressWarnings("unused")
				short confirm;
                if (data.getString("Commond").equals("set_size")) {
                	int width = data.getInt("Width");
                	int height = data.getInt("Height");
                	sendSize(width, height);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("set_pos")) {
                	int x = data.getInt("x");
                	int y = data.getInt("y");
                	sendPos(x, y);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("down")) {
                	int x = data.getInt("x");
                	int y = data.getInt("y");
                	sendMouseEvent(COMMOND_DOWN, x, y);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("up")) {
                	int x = data.getInt("x");
                	int y = data.getInt("y");
                	sendMouseEvent(COMMOND_UP, x, y);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("click")) {
                	int x = data.getInt("x");
                	int y = data.getInt("y");
                	sendMouseEvent(COMMOND_CLICK, x, y);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("move")) {
                	int x = data.getInt("x");
                	int y = data.getInt("y");
                	sendMouseEvent(COMMOND_MOVE, x, y);
                	confirm = recvConfirm();
                }
                else if (data.getString("Commond").equals("press")) {
                	int code = data.getInt("Code");
                	sendKeyboardEvent(COMMOND_PRESS, code);
                }
                else if (data.getString("Commond").equals("close")) {
                	disconnect();
                }
            }
        };
		Looper.loop();
	}
	
	public void stopThread() {
		Message msg = mHandler.obtainMessage();
		Bundle data = new Bundle();
		data.putString("Commond", "close");
		msg.setData(data);
		mHandler.sendMessage(msg);
	}
	
	private void connect() {
		try {
			mCommondSocket = new Socket(mAddress, 45678);
			//mCommondSocket.setKeepAlive(true);
			mCommondStream = mCommondSocket.getOutputStream();
			mConfirmStream = mCommondSocket.getInputStream();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void disconnect() {
		try {
			mCommondStream.close();
			mConfirmStream.close();
			mCommondSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void sendData(byte[] data, int pos, int len) {
		if (mCommondSocket == null)
			return;
		
		try {
			mCommondStream.write(data, pos, pos+len);
			mCommondStream.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private short recvConfirm() {
		try {
			mConfirmStream.read(sendBuffer, 0, 2);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ByteTools.byte2Short(sendBuffer);
	}
	
	private void sendSize(int widht, int height) {
		ByteTools.short2Byte(COMMOND_SIZE, sendBuffer);
		ByteTools.short2Byte((short) 8, sendBuffer, 2);
		ByteTools.int2Byte(widht, sendBuffer, 4);
		ByteTools.int2Byte(height, sendBuffer, 8);
		sendData(sendBuffer, 0, 12);
	}
	
	private void sendPos(int x, int y) {
		ByteTools.short2Byte(COMMOND_POS, sendBuffer);
		ByteTools.short2Byte((short) 8, sendBuffer, 2);
		ByteTools.int2Byte(x, sendBuffer, 4);
		ByteTools.int2Byte(y, sendBuffer, 8);
		sendData(sendBuffer, 0, 12);
	}
	
	private void sendMouseEvent(short com, int x, int y) {
		ByteTools.short2Byte(com, sendBuffer);
		ByteTools.short2Byte((short) 8, sendBuffer, 2);
		ByteTools.int2Byte(x, sendBuffer, 4);
		ByteTools.int2Byte(y, sendBuffer, 8);
		sendData(sendBuffer, 0, 12);
	}
	
	private void sendKeyboardEvent(short com, int code) {
		ByteTools.short2Byte(com, sendBuffer);
		ByteTools.short2Byte((short) 4, sendBuffer, 2);
		ByteTools.int2Byte(code, sendBuffer, 4);
		sendData(sendBuffer, 0, 8);
	}
}
